﻿using SuperFrame.Charts.Points;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using System.Linq;


namespace SuperFrame.Charts
{
    public class SeriesColumn : BaseFillSeries
    {
        internal PointCollection startEndPoints;
        internal List<Rect> rects;

        public SeriesColumn()
        {
            ColumnPoints = new PointCollection();
            isFill = true;
        }

        internal override SeriesContainer CreateContainer()
        {
            return new ContainerColumn();
        }

        override public void GenerateDatas()
        {
            if (this.Points != null && this.seriesContainer != null)
            {
                ColumnPoints.Clear();
                if (!isPointsGenerated)
                    Parts.Clear();
                startEndPoints = new PointCollection();
                rects = new List<Rect>();
                this.Chart.RefreshLegend(false);
                CalculateMinAndMax();
                IntializePoints();
                double WidthInterval = seriesContainer.collection.ActualWidth / (this.Points.Count + 1);
                foreach (ChartPoint point in this.Points)
                {
                    double h = this.YAxis.DataToPoint(point.YValue);
                    double x = WidthInterval * (this.Points.IndexOf(point) + 1) - ColumnWidth / 2;
                    Point startPoint = new Point(x, h);
                    double h1 = this.YAxis.DataToPoint(yMin);
                    double x1 = WidthInterval * (this.Points.IndexOf(point) + 1) + ColumnWidth / 2;
                    Point endPoint = new Point(x1, h1);
                    startEndPoints.Add(startPoint);
                    startEndPoints.Add(endPoint);

                    Point linePoint = NormalizePoint(new Point(point.XValue, point.YValue));
                    ColumnPoints.Add(linePoint);

                    rects.Add(new Rect(startPoint, endPoint));

                }
                if (this.RenderingMode == RenderingMode.Default)
                {
                    if (!isPointsGenerated)
                    {
                        for (int i = 0; i <= this.rects.Count - 1; i++)
                        {
                            PartColumn columnPart = new PartColumn(rects[i], this.Points[i].YValue+"", this.Points[i].Color);
                            //SetBindingForStrokeandStrokeThickness(columnPart);
                            this.Parts.Add(columnPart);
                        }
                        isPointsGenerated = true;
                    }
                    else
                    {
                        int i = 0;
                        foreach (PartColumn part in this.Parts)
                        {
                            part.Column = rects[i];
                            part.Refresh();
                            i++;
                        }
                    }
                }
                this.seriesContainer.Invalidate();
            }
            isRefreshed = false;
        }

        public Point CalculateSeriesColumnInfo()
        {
            double width = 1 - Chart.GetColumnMarginPercentage(this);
            double mininumWidth = double.MaxValue;
            int position = Chart.SeriesColumn.IndexOf(this) + 1;
            int count = Chart.SeriesColumn.Count;
            foreach (BaseSeries series in Chart.Series)
            {
                List<double> xValues = series.xValues as List<double>;
                if (xValues != null)
                {
                    for (int i = 1; i < xValues.Count; i++)
                    {
                        double delta = xValues[i] - xValues[i - 1];
                        if (delta != 0)
                        {
                            mininumWidth = Math.Min(mininumWidth, delta);
                        }
                    }
                }
            }
            mininumWidth = ((mininumWidth == double.MaxValue || mininumWidth >= 1 || mininumWidth < 0) ? 1 : mininumWidth);
            double per = mininumWidth * width / count;
            double start = per * (position - 1) - mininumWidth * width / 2;
            double end = start + per;
            return new Point(start, end);
        }

        public void RefreshData(CollectionPoints points)
        {
            foreach (var item in points)
            {
                int index = this.Points.IndexOf(this.Points.FirstOrDefault(s => s.ID == item.ID));
                if (index >= 0)
                {
                    this.Points[index] = item;
                }
            }
        }

        /// <summary>
        /// 柱状图宽度(默认80)
        /// </summary>
        public double ColumnWidth
        {
            get { return (double)GetValue(ColumnWidthProperty); }
            set { SetValue(ColumnWidthProperty, value); }
        }
        public static readonly DependencyProperty ColumnWidthProperty = DependencyProperty.Register("ColumnWidth", typeof(double), typeof(SeriesColumn), new PropertyMetadata(60d));


        public PointCollection ColumnPoints
        {
            get { return (PointCollection)GetValue(ColumnPointsProperty); }
            set { SetValue(ColumnPointsProperty, value); }
        }
        public static readonly DependencyProperty ColumnPointsProperty = DependencyProperty.Register("ColumnPoints", typeof(PointCollection), typeof(SeriesColumn), new PropertyMetadata(null));
    }
}
